package com.aaa.power.service.impl;

import com.aaa.common.bo.TreeNode;
import com.aaa.common.bo.User;
import com.aaa.common.constants.ExceptionConstant;
import com.aaa.common.constants.ReturnCode;
import com.aaa.common.util.CustomException;
import com.aaa.common.util.Result;
import com.aaa.power.entity.Menu;
import com.aaa.power.mapper.MenuMapper;
import com.aaa.power.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author YuXin
 * @since 2020-11-09 16:01:05
 */
@Service("menuService")
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuMapper menuMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 按照年份查询数据
     *
     * @param year
     * @return
     */
    @Override
    public Result queryOpsByYear(Integer year) {
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), menuMapper.queryOpsByYear(year));
    }
    /**
     * 通过ID查询单条数据
     *
     * @param menuId 主键
     * @return Result --- Result.getData():实例对象
     */
    @Override
    public Result queryById(Integer menuId) {
        //当业务为空时抛出自定义异常
        if (menuId == null) {
            throw new CustomException(ExceptionConstant.ID_NOT_NULL.getErrorCode(), ExceptionConstant.ID_NOT_NULL.getErrorMessage());
        }
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), this.menuMapper.queryById(menuId));
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return Result --- Result.getData():对象列表
     */
    @Override
    public Result queryAllByLimit(Integer offset, Integer limit) {
        if (offset == null || limit == null) {
            throw new CustomException(ExceptionConstant.INVALID_ARGUMENT.getErrorCode(), ExceptionConstant.INVALID_ARGUMENT.getErrorMessage());
        }
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), this.menuMapper.queryAllByLimit(offset, limit));
    }

    /**
     * 查询多条数据
     *
     * @param menu 实例对象
     * @return Result --- Result.getData():treeNodeList
     */
    @Override
    public Result queryAllToTreeNode(Menu menu) {
        //把Menu集合转换为 List<TreeNode>
        List<Menu> menuList = this.menuMapper.queryAll(null);
        //实例化集合  用于接收数据
        List<TreeNode> treeNodeList = new ArrayList<>();
        TreeNode treeNode = null;
        //循环
        if (menuList != null && menuList.size() > 0) {
            for (Menu menuStr : menuList) {
                //查找一级节点
                if (menuStr.getParentId() == 0) {
                    treeNode = this.menuToTreeNode(menuStr);
                    //查找子节点
                    bindChildren(treeNode, menuList);
                    treeNodeList.add(treeNode);
                }
            }
        }
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), treeNodeList);
    }

    /**
     * @Author: YuXin
     * @Date : Created in 2020/11/9 16:52
     * @Description :   封装一个Menu和TreeNode的转换
     * @Param :  menuStr
     * @Return :
     */
    private TreeNode menuToTreeNode(Menu menuStr) {
        TreeNode treeNode = new TreeNode();
        treeNode.setId(menuStr.getMenuId());
        treeNode.setParentId(menuStr.getParentId());
        treeNode.setLabel(menuStr.getMenuName());
        treeNode.setIcon(menuStr.getIcon());
        treeNode.setUrl(menuStr.getUrl());
        treeNode.setVisible(menuStr.getVisible());

        treeNode.setIndex(menuStr.getUrl());
        treeNode.setTitle(menuStr.getMenuName());
        return treeNode;
    }

    /**
     * @Author: YuXin
     * @Date : Created in 2020/11/9 16:52
     * @Description :   递归绑定子节点
     * @Param :  currentNode  menuList
     * @Return :
     */
    private void bindChildren(TreeNode currentNode, List<Menu> menuList) {
        for (Menu menu : menuList) {
            //如果循环节点的父id等于当前节点的id  说明循环节点是当前节点的子节点
            if (currentNode.getId() == menu.getParentId()) {
                //获取子节点集合  第一次获取时肯定是空对象
                List<TreeNode> children = currentNode.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                }
                //添加子节点
                TreeNode treeNode = this.menuToTreeNode(menu);
                children.add(treeNode);
                //绑定
                currentNode.setChildren(children);
                bindChildren(treeNode, menuList);
            }
        }
    }

    /**
     * 新增数据
     *
     * @param map 实例对象
     * @return Result --- Result.getData():实例对象
     */
    @Override
    public Result insert(Map map) {
        if (map == null) {
            throw new CustomException(ExceptionConstant.INVALID_ARGUMENT.getErrorCode(), ExceptionConstant.INVALID_ARGUMENT.getErrorMessage());
        }
        this.menuMapper.insertMenu(map);
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), map);
    }

    /**
     * 修改数据
     *
     * @param map 实例对象
     * @return Result --- Result.getData():实例对象
     */
    @Override
    public Result update(Map map) {
        if (map == null) {
            throw new CustomException(ExceptionConstant.INVALID_ARGUMENT.getErrorCode(), ExceptionConstant.INVALID_ARGUMENT.getErrorMessage());
        }
        this.menuMapper.updateMenu(map);
        Integer menuId = (Integer) map.get("id");
        return this.queryById(menuId);
    }

    /**
     * 查询非空可用url
     *
     * @return Result
     */
    @Override
    public Result queryUrlNotNull() {
        Menu menu = new Menu();
        menu.setIsNullUrl(1);
        menu.setVisible("0");
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), menuMapper.queryAll(menu));

    }

    /**
     * 通过主键删除数据
     *
     * @param menuId 主键
     * @return Result --- Result.getData():是否成功
     */
    @Override
    public Result deleteById(Integer menuId) {
        if (menuId == null) {
            throw new CustomException(ExceptionConstant.ID_NOT_NULL.getErrorCode(), ExceptionConstant.ID_NOT_NULL.getErrorMessage());
        }
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), this.menuMapper.deleteById(menuId) > 0);
    }

    /**
     * 通过角色id查询其所有menu
     *
     * @param roleId
     * @return List<Map>
     */
    @Override
    public Result selectAllMenuByRoleId(Integer roleId) {
        List<Map> menuList = menuMapper.selectAllMenuByRoleId(roleId);
        List treeList = new ArrayList();
        for (Map map : menuList) {
            treeList.add(map.get("id"));
        }
        return new Result<>(ReturnCode.SUCCESS.getCode(), ReturnCode.SUCCESS.getMsg(), treeList);
    }

    @Override
    public List<TreeNode> selectMenuTreeByToken(String token) {
        User user = (User) redisTemplate.opsForValue().get(token);

        //把Menu集合转换为 List<TreeNode>
        List<Menu> menuList = this.menuMapper.queryMenuByUserId(user.getUserId());

        //实例化集合  用于接收数据
        List<TreeNode> treeNodeList = new ArrayList<>();
        TreeNode treeNode = null;
        //循环
        if (menuList != null && menuList.size() > 0) {
            for (Menu menuStr : menuList) {
                //查找一级节点
                if (menuStr.getParentId() == 0) {
                    treeNode = this.menuToTreeNode(menuStr);
                    //查找子节点
                    bindChildren(treeNode, menuList);
                    treeNode.setSubs(treeNode.getChildren());
                    treeNodeList.add(treeNode);
                }
            }
        }
        return treeNodeList;
    }

    /**
     * 客户登录统计
     *
     * @param yearMonth
     * @return
     */
    @Override
    public Result queryByClientLogin(String yearMonth) {
        return new Result(ReturnCode.SUCCESS.getCode(),
                ReturnCode.SUCCESS.getMsg(), menuMapper.queryByClientLogin(yearMonth));
    }
}